package cn.tedu.micro.gateway.ip;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.Set;
import java.util.function.Supplier;

/**
 * 只要ip不在白名单中，就拦截
 */
@Component
public class RedisIpFilter implements GlobalFilter, Ordered {
    @Autowired
    private RedisIpListService ipListService;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpResponse response = exchange.getResponse();
        //获取请求中ip地址
        String requestIP =
                exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
        //检查黑名单
        Set<String> blackList = ipListService.getBlackList();
        if(blackList.contains(requestIP)){
            //拦截请求，直接返回403状态码
            String jsonData="{\"state\":403,\"message\":\"你没权限访问\",\"data\":null}";
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            byte[] bytes = jsonData.getBytes(StandardCharsets.UTF_8);
            DataBuffer dataBuffer = response.bufferFactory().wrap(bytes);
            Mono<DataBuffer> dataBufferMono = Mono.fromSupplier(new Supplier<DataBuffer>() {
                @Override
                public DataBuffer get() {
                    //返回上面包装好的缓冲流
                    return dataBuffer;
                }
            });
            return response.writeWith(dataBufferMono);
//            response.setStatusCode(HttpStatus.FORBIDDEN);
//            return response.setComplete();
        }
        //检查白名单，如果没有就拦截
        Set<String> whiteList = ipListService.getWhiteList();
        if(whiteList.isEmpty() || !whiteList.contains(requestIP)){
            //拦截请求，直接返回403状态码
            String jsonData="{\"state\":403,\"message\":\"你没权限访问\",\"data\":null}";
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            byte[] bytes = jsonData.getBytes(StandardCharsets.UTF_8);
            DataBuffer dataBuffer = response.bufferFactory().wrap(bytes);
            Mono<DataBuffer> dataBufferMono = Mono.fromSupplier(new Supplier<DataBuffer>() {
                @Override
                public DataBuffer get() {
                    //返回上面包装好的缓冲流
                    return dataBuffer;
                }
            });
            return response.writeWith(dataBufferMono);
//            response.setStatusCode(HttpStatus.FORBIDDEN);
//            return response.setComplete();
        }
        //白名单中有requestIP，就放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
